package trabalho.xml.dominio;

public class Jobs {
	public String strSenderName;
	
	public int intMsgID;
	
	public int intCountList;

	private int[] listaNum;
	private int[] listaLess;
	private int[] listaGreater;
	private int intMsgIdLess = 0, intMsgIdGreater = 0;
		
	public Jobs(String _senderName, int _msgId, int[] _lista){
		strSenderName = _senderName;
		intMsgID = _msgId;
		intCountList = _lista.length;
		listaNum = _lista;
		
		int[] numeros = ordenarLista();
		int i;
		i = 0;
	}
	
	public int[] ordenarLista(){
		return quicksort(listaNum, intCountList);
	}

	public int getMsgIdLess(){ return intMsgIdLess; }
	public int getMsgIdGreater(){ return intMsgIdGreater; }
	
	public void setLess(int[] _lista){
		listaLess = _lista;
	}	
	public void setGreater(int[] _lista){
		listaGreater = _lista;
	}
	
	public boolean isReplyLessReady(){
		
		if (listaLess == null)
			return false;
		else
			return true;
	}	
	public boolean isReplyGreaterReady(){
		if (listaGreater == null)
			return false;
		else
			return true;
	}
	
	int partition(int arr[], int right, int left)
	{

	      int i = right;
	      int j = left;

	      int tmp;

	      int pivot = arr[(left + right) / 2];

	     

	      while (i <= j) {

	            while (arr[i] < pivot)
	                  i++;

	            while (arr[j] > pivot)
	                  j--;

	            if (i <= j) {

	                  tmp = arr[i];

	                  arr[i] = arr[j];

	                  arr[j] = tmp;

	                  i++;

	                  j--;

	            }

	      };
	      return i;

	}
	

	void qsort(int[] array , int begin, int end)  {

		 if (end > begin) {
			 
	            int index = partition(array, begin, end);
	            
	              qsort(array, begin, index - 1);
	              qsort(array, index + 1, end);
	        
	        }

	}
	
	private int[] quicksort(int[] inlist, int length) {

		//This is our base case. If the list is one or shorter, spit it back out
		if (length <= 1){ return inlist; }

		//Our sub-lists
		int[] less = new int[length];
		int[] equal = new int[length];
		int[] greater = new int[length];

		//Our counters to keep track of the number of "good" elements in each
		int ltsize = 0;
		int eqsize = 0;
		int gtsize = 0;

		//Take our pivot
		int pivot = inlist[0];

		for(int i = 0; i < length; i++){
			//Take every item in the original list
			//And put it in its rightful place in
			//one of the sub-lists
			if (inlist[i] < pivot){
				less[ltsize] = inlist[i];
				ltsize++;
			}
			else if (inlist[i] > pivot){
				greater[gtsize] = inlist[i];
				gtsize++;
			}
			else if (inlist[i] == pivot){
				equal[eqsize] = inlist[i];
				eqsize++;
			}
		}

		//Find the sorted versions of the lists
		boolean esperaReply = false;
		if (ltsize <= 50)
			less = quicksort(less, ltsize);
		else
		{	
			//listaLess = new int[ltsize];
			intMsgIdLess = ControladorPeerJobs.getControlador().gerarNovoJobDeLista(less,intMsgID);
			esperaReply = true;
		}
		
		//Equal doesn't need to be sorted
		if (gtsize <= 50)
			greater = quicksort(greater, gtsize);
		else
		{
			//listaGreater = new int[gtsize];
			intMsgIdGreater = ControladorPeerJobs.getControlador().gerarNovoJobDeLista(greater,intMsgID);
			esperaReply = true;
		}
		
		while (esperaReply == true)
		{
			if ( isReplyLessReady() && isReplyGreaterReady())
			{
				less = listaLess;
				greater = listaGreater;
				esperaReply = false;
			}			
		}
		
		//Our list to return
		int[] ret = new int[length];
		//The index of the end of the list
		int retPointer = 0;

		//Put less into ret
		for(int i = 0; i < ltsize; i++){
			if (less[i] > 0 ){	ret[retPointer] = less[i]; }
			retPointer++;
		}

		//Put equal into ret
		for (int i = 0; i < eqsize; i++){
			if (equal[i] > 0) { ret[retPointer] = equal[i]; }
			retPointer++;
		}

		//Put greater into ret
		for (int i = 0; i < gtsize; i++){
			if (greater[i] > 0) { ret[retPointer] = greater[i]; }
			retPointer++;
		}

		//We're done!
		return ret;
	}
}
